package org.review.datastructure;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;

public class DoubleLinkedList {
    HeroNode1 head = new HeroNode1(0, "", "");

    public static void main(String[] args) {
        DoubleLinkedList list = new DoubleLinkedList();
        HeroNode1 hero1 = new HeroNode1(1, "宋江", "及时雨");
        HeroNode1 hero2 = new HeroNode1(2, "卢俊义", "玉麒麟");
        HeroNode1 hero3 = new HeroNode1(3, "吴用", "智多星");
        HeroNode1 hero4 = new HeroNode1(4, "林冲", "豹子头");

        list.add(hero1);
        list.add(hero2);
        list.add(hero3);
        list.add(hero4);
        list.showHero();

        System.out.println("=============================================按照顺序添加");
        HeroNode1 hero5 = new HeroNode1(2, "卢俊义", "玉麒麟");
        HeroNode1 hero6 = new HeroNode1(5, "孙二娘", "母夜叉");
        list.addByOrder(hero5);
        list.addByOrder(hero6);
        list.showHero();
        System.out.println("=============================================修改节点后");
        list.updateHero(new HeroNode1(6, "孙二娘1", "母夜叉好牛"));
        list.showHero();

        System.out.println("=============================================删除元素");
        list.delHero(2);
        list.showHero();

    }

    public void showHero() {
        HeroNode1 temp = head.next;

        while (true) {
            if (temp == null) break;
            System.out.println(temp);
            temp = temp.next;
        }
    }

    public void add(HeroNode1 heroNode) {
        HeroNode1 temp = head;

        while (true) {
            if (temp.next == null) break;
            temp = temp.next;
        }
        heroNode.pre = temp;
        temp.next = heroNode;
    }

    public void addByOrder(HeroNode1 hero) {

        HeroNode1 current = head;

        boolean flag = false;
        //todo 方式1  这个实现方式有一点笨拙
/*        while (true) {
            if (current.next == null) break;

            if (current.next.no > hero.no) {
                flag = true;
                break;
            }
            current = current.next;
        }
        if (flag) { //todo 这里跟单链表反转有异曲同工之妙  一定要记得新增节点的next 需要等于current.next,否则就断了
            HeroNode1 temp = current.next;
            current.next = hero;
            hero.pre = current;
            hero.next = temp;
        } else {
            current.next = hero;
            hero.pre = current;
        }*/
        //TODO  方式2  交换节点需要捋一下再写
        while (current.next != null && current.next.no <= hero.no) {
            current = current.next;
        }
        HeroNode1 temp = current.next;
        current.next = hero;
        hero.next = temp;
        hero.pre = current;
    }

    public void updateHero(HeroNode1 hero) {

        //TODO 实现方式1  比较逻辑比较简单，比较容易理解
 /*        HeroNode1 current = head.next;
       boolean flag = false;
        while (true) {
            if (current == null) break;
            if (current.name.equals(hero.name)) {
                flag = true;
                break;
            }
            current = current.next;
        }

        if (flag) {
            current.no = hero.no;
            current.nickname = hero.nickname;
        }else {
            System.out.println("没有找到此节点");
        }*/

        //TODO 实现方式2 优点：逻辑较复杂 代码简洁
        HeroNode1 current = head;
        //TODO 如果curren.next=null就是没找到，如果current.next.name =hero.name 就更新
        while (current.next != null && !current.next.name.equals(hero.name)) {
            current = current.next;
        }
        if (current.next == null) {
            return;
        }
        current.next.no = hero.no;
        current.next.nickName = hero.nickName;

    }

    public void delHero(int no) {

        //TODO 实现方式1
       /* HeroNode1 current = head.next;

        boolean flag = false;
        while (true) {
            if (current == null) {
                break;
            }
            if (current.no == no) {
                flag = true;
                break;
            }
            current = current.next;
        }

        if (flag) {

            //TODO  单列表 current.next = current.next.next;
            current.pre.next = current.next;
            if (current.next != null) { //TODO current.next 不等于null 否则会报空指针，也没有意义
                current.next.pre = current.pre;
            }
        } else {
            System.out.println("没找到此元素");
        }*/

        //TODO 实现方式2
        HeroNode1 current = head.next;
        while (current != null && current.no != no) {
            current = current.next;
        }

        if (current == null) {
            System.out.println("没有此节点");
            return;
        }
        current.pre.next = current.next;
        if (current.next == null) return;

        current.next.pre = current.pre;

        //TODO  如果使用current.next.no判断 应该如下操作删除
        /*current.next = current.next.next;
        current.next.next.pre = current;*/
    }
}

@RequiredArgsConstructor
class HeroNode1 {
    @NonNull
    public int no;
    @NonNull
    public String name;
    @NonNull
    public String nickName;
    public HeroNode1 next;
    public HeroNode1 pre;

    @Override
    public String toString() {
        return "HeroNode1{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickName + '\'' + '}';
    }
}